package com.roam.Ant;

import com.roam.VO.TourPlanVO;
import com.roam.entity.scene.Coordinate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class AntColonyOptimization {
    private static final int MAX_ITERATIONS = 100; // 最大迭代次数
    private static final int NUM_ANTS = 10; // 蚂蚁数量
    private static final double ALPHA = 1.0; // 信息素重要程度
    private static final double BETA = 2.0; // 启发式因子重要程度
    private static final double EVAPORATION_RATE = 0.5; // 信息素挥发率
    private static final double INITIAL_PHEROMONE = 1.0; // 初始信息素浓度
    private static final double Q = 500.0; // 信息素增加强度

    private List<TourPlanVO> tourPlan;
    private double[][] distanceMatrix;
    private double[][] pheromoneMatrix;
    private List<List<TourPlanVO>> bestPaths;   //每次迭代的最佳路径
    private double bestPathLength;

    public AntColonyOptimization(List<TourPlanVO> tourPlan) {
        this.tourPlan = tourPlan;
        initializeDistanceMatrix();
        initializePheromoneMatrix();
    }

    // 初始化距离矩阵
    private void initializeDistanceMatrix() {
        int size = tourPlan.size();
        distanceMatrix = new double[size][size];
        for (int i = 0; i < size; i++) {
            for (int j = i + 1; j < size; j++) {
                double distance = calculateDistance(tourPlan.get(i).getCoordinate(), tourPlan.get(j).getCoordinate());
                distanceMatrix[i][j] = distance;
                distanceMatrix[j][i] = distance;
            }
        }
    }

    // 初始化信息素矩阵
    private void initializePheromoneMatrix() {
        int size = tourPlan.size();
        pheromoneMatrix = new double[size][size];
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                pheromoneMatrix[i][j] = INITIAL_PHEROMONE;
            }
        }
    }

    // 计算两个坐标点之间的距离
    private double calculateDistance(Coordinate c1, Coordinate c2) {
        // 省略距离计算代码
        return 0.0; // 这里应该是实际的距离计算
    }

    // 运行蚁群算法
    public void runAntColonyOptimization() {
        bestPaths = new ArrayList<>();
        bestPathLength = Double.MAX_VALUE;

        for (int iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
            List<List<TourPlanVO>> antPaths = new ArrayList<>();
            double[] pathLengths = new double[NUM_ANTS];

            for (int ant = 0; ant < NUM_ANTS; ant++) {
                List<TourPlanVO> antPath = constructAntPath();
                antPaths.add(antPath);
                pathLengths[ant] = calculatePathLength(antPath);
                updatePheromone(antPath, pathLengths[ant]);
            }

            // 更新最佳路径
            for (int ant = 0; ant < NUM_ANTS; ant++) {
                if (pathLengths[ant] < bestPathLength) {
                    bestPaths.clear();
                    bestPaths.add(antPaths.get(ant));
                    bestPathLength = pathLengths[ant];
                } else if (pathLengths[ant] == bestPathLength) {
                    bestPaths.add(antPaths.get(ant));
                }
            }

            // 挥发信息素
            evaporatePheromone();
        }

    }

    // 构造单个蚂蚁的路径
    private List<TourPlanVO> constructAntPath() {
        List<TourPlanVO> antPath = new ArrayList<>();
        List<TourPlanVO> remainingCities = new ArrayList<>(tourPlan);

        if (remainingCities.isEmpty()) {
            // 处理空列表的情况，这里选择返回空路径或者抛出异常
            return antPath; // 返回空路径
        }

        TourPlanVO currentCity = remainingCities.remove(0);
        antPath.add(currentCity);

        while (!remainingCities.isEmpty()) {
            currentCity = selectNextCity(currentCity, remainingCities);
            antPath.add(currentCity);
            remainingCities.remove(currentCity);
        }

        return antPath;
    }

    // 选择下一个城市
    private TourPlanVO selectNextCity(TourPlanVO currentCity, List<TourPlanVO> remainingCities) {
        double[] probabilities = new double[remainingCities.size()];
        double totalProbability = 0.0;

        int currentIndex = tourPlan.indexOf(currentCity);

        if (remainingCities.isEmpty()) {
            // 返回null表示没有可选的下一个城市
            return null;
        }

        for (int i = 0; i < remainingCities.size(); i++) {
            TourPlanVO city = remainingCities.get(i);
            int nextIndex = tourPlan.indexOf(city);
            double pheromone = pheromoneMatrix[currentIndex][nextIndex];
            double distance = distanceMatrix[currentIndex][nextIndex];

            probabilities[i] = Math.pow(pheromone, ALPHA) * Math.pow(1.0 / distance, BETA);
            totalProbability += probabilities[i];
        }

        double random = Math.random() * totalProbability;
        double cumulativeProbability = 0.0;

        for (int i = 0; i < probabilities.length; i++) {
            cumulativeProbability += probabilities[i];
            if (cumulativeProbability >= random) {
                return remainingCities.get(i);
            }
        }

        return remainingCities.get(remainingCities.size() - 1);
    }

    // 计算路径长度
    private double calculatePathLength(List<TourPlanVO> path) {
        double length = 0.0;

        for (int i = 0; i < path.size() - 1; i++) {
            TourPlanVO city1 = path.get(i);
            TourPlanVO city2 = path.get(i + 1);
            length += distanceMatrix[tourPlan.indexOf(city1)][tourPlan.indexOf(city2)];
        }

        return length;
    }

    // 更新信息素
    private void updatePheromone(List<TourPlanVO> path, double pathLength) {
        double pheromoneDelta = Q / pathLength;

        for (int i = 0; i < path.size() - 1; i++) {
            TourPlanVO city1 = path.get(i);
            TourPlanVO city2 = path.get(i + 1);
            int index1 = tourPlan.indexOf(city1);
            int index2 = tourPlan.indexOf(city2);
            pheromoneMatrix[index1][index2] += pheromoneDelta;
            pheromoneMatrix[index2][index1] += pheromoneDelta;
        }
    }

    // 挥发信息素
    private void evaporatePheromone() {
        for (int i = 0; i < pheromoneMatrix.length; i++) {
            for (int j = 0; j < pheromoneMatrix[i].length; j++) {
                pheromoneMatrix[i][j] *= (1 - EVAPORATION_RATE);
            }
        }
    }

    // 获取最佳路径的方法
    public List<TourPlanVO> getBestPath() {
        List<TourPlanVO> bestPath=new ArrayList<>();
        double shortestDistance = Double.MAX_VALUE;

        // 遍历所有记录的路径
        for (List<TourPlanVO> path : bestPaths) {
            double distance = calculatePathLength(path); // 计算路径长度

            // 更新最短路径和最小距离
            if (distance < shortestDistance) {
                shortestDistance = distance;
                bestPath = path;
            }
        }
        return bestPath;
    }

    // 获取最佳路径长度
    public double getBestPathLength() {
        return bestPathLength;
    }

    // 省略坐标类的定义
}